fix(orchestrator): Skip blank subagent opening messages - #5456
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
25de21d to
0af2a6e
Compare
A provider-native subagent could open its child thread with an empty or whitespace-only user message, which renders as an empty bubble under the "Sent by another agent" label. The Claude adapter emitted the opening prompt whenever the subagent was new, and a task_progress frame can register a subagent before any frame carries its prompt, so the message was emitted with the "" default and never rewritten when the real prompt arrived on a later task_started. A shared hasSubagentPromptText guard now gates every subagent opening message. The Claude adapter emits it the first time the task prompt actually has text rather than on first registration, so a late prompt still opens the child thread exactly once. Codex's existing length check becomes trim-aware, and Cursor and ACP pick up the same guard.
0e1b4fe to
1598863
Compare
ApprovabilityVerdict: Needs human review Diff is too large for automated approval analysis. A human reviewer should evaluate this PR. You can customize Macroscope's approvability policy. Learn more. |
Carried from another PR
fix(orchestration): Preserve Claude subagent attribution after settle—carried for #5388 claude-postsettle-attribution.
Review it there, not here.
fix(orchestrator): Skip blank subagent opening messages— this PR.Summary
whitespace-only user message under the "Sent by another agent" label.
Claude's opening message the first time the task prompt has real text rather
than on first registration.
t3code/codex-turn-mapping.Problem and Fix
promptis whitespace-only still produced a child user message. The Agent tool accepts it,task_startedcarries it, and the emission site had no emptiness guard, so the web timeline rendered an empty bubble.hasSubagentPromptTexttrims before deciding. EverymakeSubagentConversationArtifactscaller withrole: "user"goes through it (Claude, Codex, Cursor, ACP).task_progressframe can register a Claude subagent before any prompt-bearing frame. Registration fell back toprompt: input.prompt ?? "", and the opening message was tied to first registration, so it was emitted as""and never rewritten when a latertask_startedsupplied the real prompt.hasSubagentPromptText(task.prompt) && !hasSubagentPromptText(priorTask?.prompt), so a late prompt still opens the child exactly once and a prompt change from one non-empty value to another does not re-emit.input.prompt.length > 0, which still admits whitespace. Cursor and ACP had no guard.Validation
claude_subagent_empty_promptcovers both routes (whitespace Agent prompt andtask_progressbeforetask_started). Confirmed fail before the emission fix and pass after.OrchestratorReplayFixtures.integration/.contract,ClaudeReplayFixtures.integration,CodexReplayFixtures.integration): 89 tests, 1 skipped.SubagentProjection): 274 tests.vp check: passed.vp run typecheck: passed all 15 packages.prompt: " "and a child thread with no user message; a sibling ordinary-prompt child held exactly one:promptmessage. Zero trim-empty user-role projection messages in the isolated DB.Checklist
Note
Low Risk
Server-side projection guard only; no auth, persistence schema, or API contract changes beyond omitting empty timeline messages.
Overview
ACP adapter now wraps subagent opening user
message.updated/turn_item.updatedemission inhasSubagentPromptText(update.prompt), so child threads are not seeded with a blank “Sent by another agent” bubble when the provider supplies an empty or whitespace-only prompt.Subagent registration and other subagent events are unchanged; only the optional
:promptconversation artifacts are skipped when there is no real prompt text (trim-aware check fromSubagentProjection).Reviewed by Cursor Bugbot for commit 1598863. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Skip blank subagent opening messages in Claude, ACP, Codex, and Cursor adapters
hasSubagentPromptTextto SubagentProjection.ts to returntrueonly when a prompt contains non-whitespace text; gates opening user message and turn item emissions in all four provider adapters on this check.Semaphore, and deduplicate progress/result emissions; subagent-originated approval flows are now supported.messageTextoverride andfailIfCurrenthook toProviderContinuationRequest, allowing adapters to customize continuation message text and clean up state on dispatch failure.'Background task completed.'provider-buffered continuation messages from the visible run queue inderiveThreadQueueWorkflowState.claude_subagent_empty_promptto cover the blank-prompt subagent scenario end-to-end.Macroscope summarized 1598863.